package com.tools.controller;

import animatefx.animation.FadeInUp;
import com.tools.MainApp;
import com.tools.utils.AlertUtil;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.layout.BorderPane;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import org.apache.log4j.Logger;

import java.io.IOException;
import java.lang.ref.SoftReference;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

/**
 * BaseController
 *
 * @author < a href=" ">ZhangYang</ a>
 * @version v1.0.01
 * @date 2018-07-31 12:29:24
 */

public abstract class BaseController implements Initializable {
  private static final Logger LOG = Logger.getLogger(BaseController.class);

  private Stage primaryStage;
  private Stage dialogStage;
  private BorderPane index;
  private MainApp mainApp;

  private static Map<FXMLPage, SoftReference<? extends BaseController>> cacheNodeMap = new HashMap<>();

  /**
   * 加载一个页面
   *
   * @param title 页面标题
   * @param fxmlPage 页面FXML路径
   * @param cache 是否换缓存
   *
   * @return
   */
  public BaseController loadFXMLPage(String title, FXMLPage fxmlPage, boolean max, boolean cache) {
    return loadFXMLPage(title, fxmlPage, max, true, cache);
  }

  /**
   * 加载一个页面
   *
   * @param title 页面标题
   * @param fxmlPage 页面FXML路径
   * @param max 是否可以窗口最大化
   * @param resize 是否可以拖动窗口
   * @param cache 是否换缓存
   *
   * @return
   */
  public BaseController loadFXMLPage(String title, FXMLPage fxmlPage, boolean max, boolean resize, boolean cache) {
    SoftReference<? extends BaseController> parentNodeRef = cacheNodeMap.get(fxmlPage);
    if (cache && parentNodeRef != null) {
      return parentNodeRef.get();
    }
    URL skeletonResource = Thread.currentThread().getContextClassLoader().getResource(fxmlPage.getFxml());

    FXMLLoader loader = new FXMLLoader(skeletonResource);

    Parent fxmlNode;
    try {
      fxmlNode = loader.load();
      BaseController controller = loader.getController();
      new FadeInUp(fxmlNode).setResetOnFinished(true).play();
      dialogStage = new Stage();
      dialogStage.setTitle(title);
      dialogStage.initModality(Modality.APPLICATION_MODAL);
      dialogStage.initOwner(getPrimaryStage());
      dialogStage.initStyle(StageStyle.UNIFIED);
      dialogStage.setScene(new Scene(fxmlNode));
      dialogStage.setMaximized(max);
      dialogStage.setResizable(resize);
      Image image = new Image("image/tools.png", 100, 150, false, false);
      dialogStage.getIcons().add(image);
      dialogStage.show();
      controller.setDialogStage(dialogStage);
      SoftReference<BaseController> softReference = new SoftReference<>(controller);
      cacheNodeMap.put(fxmlPage, softReference);
      return controller;
    } catch (IOException e) {
      AlertUtil.showErrorAlert(e.getMessage());
    }
    return null;
  }


  /**
   * 加载一个无边框页面
   *
   * @param title
   * @param fxmlPage
   * @param cache
   *
   * @return
   */
  public BaseController loadFXMLPageUndecorated(String title, FXMLPage fxmlPage, boolean cache) {
    SoftReference<? extends BaseController> parentNodeRef = cacheNodeMap.get(fxmlPage);
    if (cache && parentNodeRef != null) {
      return parentNodeRef.get();
    }
    URL skeletonResource = Thread.currentThread().getContextClassLoader().getResource(fxmlPage.getFxml());

    FXMLLoader loader = new FXMLLoader(skeletonResource);

    Parent fxmlNode;
    try {
      fxmlNode = loader.load();
      new FadeInUp(fxmlNode).setResetOnFinished(true).play();
      BaseController controller = loader.getController();
      dialogStage = new Stage();
      dialogStage.setTitle(title);
      dialogStage.initModality(Modality.APPLICATION_MODAL);
      dialogStage.initOwner(getPrimaryStage());
      dialogStage.initStyle(StageStyle.UNDECORATED);
      dialogStage.setScene(new Scene(fxmlNode));
      dialogStage.setMaximized(false);
      dialogStage.setResizable(false);
      dialogStage.show();
      controller.setDialogStage(dialogStage);
      SoftReference<BaseController> softReference = new SoftReference<>(controller);
      cacheNodeMap.put(fxmlPage, softReference);
      return controller;
    } catch (IOException e) {
      AlertUtil.showErrorAlert(e.getMessage());
    }
    return null;
  }

  public Stage getPrimaryStage() {
    return primaryStage;
  }

  public void setPrimaryStage(Stage primaryStage) {
    this.primaryStage = primaryStage;
  }

  public Stage getDialogStage() {
    return dialogStage;
  }

  public void setDialogStage(Stage dialogStage) {
    this.dialogStage = dialogStage;
  }

  public BorderPane getIndex() {
    return index;
  }

  public void setIndex(BorderPane index) {
    this.index = index;
  }

  public MainApp getMainApp() {
    return mainApp;
  }

  public void setMainApp(MainApp mainApp) {
    this.mainApp = mainApp;
  }

  public void showDialogStage() {
    if (dialogStage != null) {
      dialogStage.show();
    }
  }

  public void closeDialogStage() {
    if (dialogStage != null) {
      dialogStage.close();
    }
  }

  public void closeDialogStageByMap(FXMLPage fxmlPage) {
    if (cacheNodeMap.get(fxmlPage).get().getDialogStage() != null) {
      cacheNodeMap.get(fxmlPage).get().getDialogStage().close();
    }
  }

}
